home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / emacs / emacs1857 / src_d2.zoo / source / buffer.c < prev    next >
C/C++ Source or Header  |  1991-12-09  |  44KB  |  1,357 lines

  1. /* Buffer manipulation primitives for GNU Emacs.
  2.    Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include <sys/param.h>
  22.  
  23. #ifndef MAXPATHLEN
  24. /* in 4.1, param.h fails to define this. */
  25. #define MAXPATHLEN 1024
  26. #endif /* not MAXPATHLEN */
  27.  
  28. #ifdef NULL
  29. #undef NULL
  30. #endif
  31. #include "config.h"
  32. #include "lisp.h"
  33. #include "window.h"
  34. #include "commands.h"
  35. #include "buffer.h"
  36. #include "syntax.h"
  37.  
  38. struct buffer *current_buffer;        /* the current buffer */
  39.  
  40. /* First buffer in chain of all buffers (in reverse order of creation).
  41.    Threaded through ->next.  */
  42.  
  43. struct buffer *all_buffers;
  44.  
  45. /* This structure holds the default values of the buffer-local variables
  46.    defined with DEFVAR_PER_BUFFER, that have special slots in each buffer.
  47.    The default value occupies the same slot in this structure
  48.    as an individual buffer's value occupies in that buffer.
  49.    Setting the default value also goes through the alist of buffers
  50.    and stores into each buffer that does not say it has a local value.  */
  51.  
  52. struct buffer buffer_defaults;
  53. /* A Lisp_Object pointer to the above, used for staticpro */
  54. static Lisp_Object Vbuffer_defaults;
  55.  
  56. /* This structure marks which slots in a buffer have corresponding
  57.    default values in buffer_defaults.
  58.    Each such slot has a nonzero value in this structure.
  59.    The value has only one nonzero bit.
  60.  
  61.    When a buffer has its own local value for a slot,
  62.    the bit for that slot (found in the same slot in this structure)
  63.    is turned on in the buffer's local_var_flags slot.
  64.  
  65.    If a slot in this structure is -1, then even though there may
  66.    be a DEFVAR_PER_BUFFER for the slot, there is no default value for it;
  67.    and the corresponding slot in buffer_defaults is not used.
  68.  
  69.    If a slot is -2, then there is no DEFVAR_PER_BUFFER for it,
  70.    but there is a default value which is copied into each buffer.
  71.  
  72.    If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
  73.    zero, that is a bug */
  74.  
  75. struct buffer buffer_local_flags;
  76.  
  77. /* This structure holds the names of symbols whose values may be
  78.    buffer-local.  It is indexed and accessed in the same way as the above. */
  79.  
  80. struct buffer buffer_local_symbols;
  81. /* A Lisp_Object pointer to the above, used for staticpro */
  82. static Lisp_Object Vbuffer_local_symbols;
  83.  
  84. Lisp_Object Fset_buffer ();
  85.  
  86. /* Alist of all buffer names vs the buffers. */
  87. /* This used to be a variable, but is no longer,
  88.  to prevent lossage due to user rplac'ing this alist or its elements.  */
  89. Lisp_Object Vbuffer_alist;
  90.  
  91. Lisp_Object Qfundamental_mode, Qmode_class;
  92.  
  93. Lisp_Object QSFundamental;    /* A string "Fundamental" */
  94.  
  95. /* For debugging; temporary.  See set_buffer_internal.  */
  96. /* Lisp_Object Qlisp_mode, Vcheck_symbol; */
  97.  
  98. nsberror (spec)
  99.      Lisp_Object spec;
  100. {
  101.   if (XTYPE (spec) == Lisp_String)
  102.     error ("No buffer named %s", XSTRING (spec)->data);
  103.   error ("Invalid buffer argument");
  104. }
  105.  
  106. DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 0, 0,
  107.   "Return a list of all buffers.")
  108.   ()
  109. {
  110.   return Fmapcar (Qcdr, Vbuffer_alist);
  111. }
  112.  
  113. DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
  114.   "Return the buffer named NAME (a string).\n\
  115. It is found by looking up NAME in  buffer-alist.\n\
  116. If there is no buffer named NAME, nil is returned.\n\
  117. NAME may also be a buffer; it is returned.")
  118.   (name)
  119.      register Lisp_Object name;
  120. {
  121.   if (XTYPE (name) == Lisp_Buffer)
  122.     return name;
  123.   CHECK_STRING (name, 0);
  124.  
  125.   return Fcdr (Fassoc (name, Vbuffer_alist));
  126. }
  127.  
  128. DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
  129.   "Return the buffer visiting file FILENAME (a string).\n\
  130. If there is no such buffer, nil is returned.")
  131.   (filename)
  132.      register Lisp_Object filename;
  133. {
  134.   register Lisp_Object tail, buf, tem;
  135.   CHECK_STRING (filename, 0);
  136.   filename = Fexpand_file_name (filename, Qnil);
  137.  
  138.   for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr)
  139.     {
  140.       buf = Fcdr (XCONS (tail)->car);
  141.       if (XTYPE (buf) != Lisp_Buffer) continue;
  142.       if (XTYPE (XBUFFER (buf)->filename) != Lisp_String) continue;
  143.       tem = Fstring_equal (XBUFFER (buf)->filename, filename);
  144.       if (!NULL (tem))
  145.     return buf;
  146.     }
  147.   return Qnil;
  148. }
  149.  
  150. DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
  151.   "Like get-buffer but creates a buffer named NAME and returns it if none already exists.")
  152.   (name)
  153.      register Lisp_Object name;
  154. {
  155.   register Lisp_Object buf, function, tem;
  156.   int count = specpdl_ptr - specpdl;
  157.   register struct buffer *b;
  158.   register unsigned char *data;
  159.   /* register struct buffer *bx; */
  160.  
  161.   buf = Fget_buffer (name);
  162.   if (!NULL (buf)) return buf;
  163.  
  164.   b = (struct buffer *) malloc (sizeof (struct buffer));
  165.   if (!b) memory_full ();
  166.  
  167.   BUF_GAP_SIZE (b) = 20;
  168.   data = (unsigned char *) malloc (BUF_GAP_SIZE (b));
  169.   if (!data)
  170.     {
  171.       free (b);
  172.       memory_full ();
  173.     }
  174.   BUF_BEG_ADDR (b) = data;
  175.   BUF_PT (b) = 1;
  176.   BUF_GPT (b) = 1;
  177.   BUF_BEGV (b) = 1;
  178.   BUF_ZV (b) = 1;
  179.   BUF_Z (b) = 1;
  180.   BUF_MODIFF (b) = 1;
  181.  
  182.   /* Put this on the chain of all buffers including killed ones.  */
  183.   b->next = all_buffers;
  184.   all_buffers = b;
  185.  
  186.   /* Put this in the alist of all live buffers.  */
  187.   XSET (buf, Lisp_Buffer, b);
  188. #if 0
  189.   XSETTYPE (buf, Lisp_Buffer);
  190.   bx = b;            /* Use of bx avoids compiler bug on Sun */
  191.   XSETBUFFER (buf, bx);
  192. #endif
  193.   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
  194.  
  195.   b->mark = Fmake_marker ();
  196.   b->markers = Qnil;
  197.   b->name = name;
  198.  
  199.   /* Enable undo in this buffer unless name starts with a space.  */
  200.   if (XSTRING (name)->data[0] != ' ')
  201.     b->undo_list = Qnil;
  202.   else
  203.     b->undo_list = Qt;
  204.  
  205.   reset_buffer (b);
  206.  
  207.   function = buffer_defaults.major_mode;
  208.   if (NULL (function))
  209.     {
  210.       tem = Fget (current_buffer->major_mode, Qmode_class);
  211.       if (EQ (tem, Qnil))
  212.     function = current_buffer->major_mode;
  213.     }
  214.  
  215.   if (NULL (function) || EQ (function, Qfundamental_mode))
  216.     return buf;
  217.  
  218.   /* To select a nonfundamental mode,
  219.      select the buffer temporarily and then call the mode function. */
  220.  
  221.   record_unwind_protect (save_excursion_restore, save_excursion_save ());
  222.  
  223.   Fset_buffer (buf);
  224.   call0 (function);
  225.  
  226.   unbind_to (count);
  227.   return buf;
  228. }
  229.  
  230. /* Reinitialize everything about a buffer except its name and contents.  */
  231.  
  232. void
  233. reset_buffer (b)
  234.      register struct buffer *b;
  235. {
  236.   b->filename = Qnil;
  237.   b->directory = (current_buffer) ? current_buffer->directory : Qnil;
  238.   b->modtime = 0;
  239.   b->save_modified = 1;
  240.   b->save_length = 0;
  241.   b->last_window_start = 1;
  242.   b->backed_up = Qnil;
  243.   b->auto_save_modified = 0;
  244.   b->auto_save_file_name = Qnil;
  245.   b->read_only = Qnil;
  246.   reset_buffer_local_variables(b);
  247. }
  248.  
  249. reset_buffer_local_variables(b)
  250.      register struct buffer *b;
  251. {
  252.   register int offset;
  253.  
  254.   /* Reset the major mode to Fundamental, together with all the
  255.      things that depend on the major mode.
  256.      default-major-mode is handled at a higher level.
  257.      We ignore it here.  */
  258.   b->major_mode = Qfundamental_mode;
  259.   b->keymap = Qnil;
  260.   b->abbrev_table = Vfundamental_mode_abbrev_table;
  261.   b->mode_name = QSFundamental;
  262.  
  263.   /* Reset all per-buffer variables to their defaults.  */
  264.   b->local_var_alist = Qnil;
  265.   b->local_var_flags = 0;
  266.  
  267.   /* For each slot that has a default value,
  268.      copy that into the slot.  */
  269.  
  270.   for (offset = (char *)&buffer_local_flags.name - (char *)&buffer_local_flags;
  271.        offset < sizeof (struct buffer);
  272.        offset += sizeof (Lisp_Object)) /* sizeof int == sizeof Lisp_Object */
  273.     if (*(int *)(offset + (char *) &buffer_local_flags)